home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /*
- * gdevilbm.c
- * deepilbm driver for GhostScript
- * this is a straight-forward modification of gdevpbm.c
- * Author: Andreas Heitmann
- */
-
- #define DINA4
- #define COMPRESSION cmpByteRun1
- #define X_DPI 72
- #define Y_DPI 72
-
- #include <stdio.h>
- #include <dos/dos.h>
- #include <utility/hooks.h>
- #include <libraries/iffparse.h>
- #include <clib/iffparse_protos.h>
- #include "gdevilbm.h"
- #include "gdevprn.h"
- #include "gxlum.h"
- #include "ilbmpacker.h"
-
- struct IFFParseBase *IFFParseBase=NULL;
-
- typedef struct gx_device_ilbm_s {
- gx_device_common;
- gx_prn_device_common;
- struct IFFHandle *iff; /* IFF Handle */
- byte palette[256][3]; /* CLUT palette */
- gx_color_index ncols; /* number of allocated colors in CLUT */
- byte compression; /* cmpRun || cmpNone */
- } ilbm_device;
-
- #define ilbm_prn_device(\
- procs,dev_name,\
- num_comp, depth, max_gray, max_rgb,\
- print_page) {\
- prn_device_body(\
- ilbm_device,\
- procs, dev_name,\
- WIDTH_10THS, HEIGHT_10THS, X_DPI, Y_DPI, 0, 0, 0, 0,\
- num_comp, depth, max_gray, max_rgb, max_gray + 1, \
- max_rgb + 1, print_page\
- )\
- }
-
-
- /* For ILBM we need our own color mapping procedures. */
- private dev_proc_map_rgb_color(ilbm24_map_rgb_color);
- private dev_proc_map_color_rgb(ilbm24_map_color_rgb);
- private dev_proc_print_page(ilbm24_print_page);
-
- private dev_proc_map_rgb_color(ilbm8_map_rgb_color);
- private dev_proc_map_color_rgb(ilbm8_map_color_rgb);
- private dev_proc_print_page(ilbm8_print_page);
-
- private dev_proc_output_page(gdev_ilbm_output_page);
- private dev_proc_open_device(gdev_ilbm_open);
-
- /* The device procedures */
- private gx_device_procs ilbm24_procs =
- prn_color_procs(
- gdev_ilbm_open,
- gdev_ilbm_output_page,
- gdev_prn_close,
- ilbm24_map_rgb_color,
- ilbm24_map_color_rgb);
-
- private gx_device_procs ilbm8_procs =
- prn_color_procs(
- gdev_ilbm_open,
- gdev_ilbm_output_page,
- gdev_prn_close,
- ilbm8_map_rgb_color,
- ilbm8_map_color_rgb);
-
- /* The device descriptors themselves */
- ilbm_device gs_ilbm24_device =
- ilbm_prn_device(ilbm24_procs,"ilbm24",3,24,255,255,ilbm24_print_page);
-
- ilbm_device gs_ilbm8_device=
- ilbm_prn_device(ilbm8_procs,"ilbm8",3,8,31,4,ilbm8_print_page);
-
- /* Map an RGB color to a ILBM24 color tuple. */
- private gx_color_index
- ilbm24_map_rgb_color(gx_device * dev, ushort r, ushort g, ushort b)
- {
- return
- (gx_color_value_to_byte(r)<<16)+
- (gx_color_value_to_byte(g)<<8)+
- gx_color_value_to_byte(b);
- }
-
- /*
- * Map a ILBM24 color tuple back to an RGB color.
- */
- private int
- ilbm24_map_color_rgb(gx_device * dev, gx_color_index color, ushort prgb[3])
- {
- prgb[0] = gx_color_value_from_byte((color>>16)&0xff);
- prgb[1] = gx_color_value_from_byte((color>> 8)&0xff);
- prgb[2] = gx_color_value_from_byte( color &0xff);
- return 0;
- }
-
- /*
- * 8-Bit Color-Mapping routines
- * Map an RGB color to a CLUT index
- */
- private gx_color_index
- ilbm8_map_rgb_color(gx_device *pdev, ushort r, ushort g, ushort b)
- {
- byte red_val, green_val, blue_val;
- gx_color_index i;
- static int warn = 1;
- gx_color_index ret = gx_no_color_index;
-
- red_val =gx_color_value_to_byte(r);
- green_val=gx_color_value_to_byte(g);
- blue_val =gx_color_value_to_byte(b);
-
- /*
- * Look for an exact match among the colors already allocated. This
- * includes the pre-allocated default color cube.
- */
- for (i = 0; i < bdev->ncols; i++) {
- if (bdev->palette[i][0] == red_val &&
- bdev->palette[i][1] == green_val &&
- bdev->palette[i][2] == blue_val) {
- ret = i;
- }
- }
- if (ret==gx_no_color_index) {
- if (bdev->ncols >= (1 <<bdev->color_info.depth)) {
- if (warn) {
- eprintf("gs: last spare color map entry allocated\n");
- warn = 0;
- }
- }
- else {
- bdev->palette[i][0]=red_val;
- bdev->palette[i][1]=green_val;
- bdev->palette[i][2]=blue_val;
- bdev->ncols++;
- ret = i;
- } /* else alloc new color */
- } /* end if no spare colors */
- return ret;
- }
-
- /*
- * Map a CLUT index to an RGB-value
- */
- private int
- ilbm8_map_color_rgb(gx_device *pdev, gx_color_index color, ushort prgb[3])
- {
- prgb[0]=gx_color_value_from_byte(bdev->palette[color][0]);
- prgb[1]=gx_color_value_from_byte(bdev->palette[color][1]);
- prgb[2]=gx_color_value_from_byte(bdev->palette[color][2]);
- return 0;
- }
-
- /* ------ Individual page printing routines ------ */
-
- private int
- print_iff_header(gx_device_printer *pdev)
- {
- struct BitMapHeader pagebmhd;
-
- PushChunk(bdev->iff,ID_ILBM,ID_BMHD,sizeof(pagebmhd));
- pagebmhd.w=bdev->width;
- pagebmhd.h=bdev->height;
- pagebmhd.x=0;
- pagebmhd.y=0;
- pagebmhd.nPlanes=bdev->color_info.depth;
- pagebmhd.masking=mskNone;
- pagebmhd.compression=bdev->compression;
- pagebmhd.pad1=0;
- pagebmhd.transparentColor=0;
- pagebmhd.xAspect=10;
- pagebmhd.yAspect=10;
- pagebmhd.pageWidth=bdev->width;
- pagebmhd.pageHeight=bdev->height;
- WriteChunkBytes(bdev->iff,&pagebmhd,sizeof(pagebmhd));
- PopChunk(bdev->iff);
- if(bdev->color_info.depth<24) {
- PushChunk(bdev->iff,ID_ILBM,ID_CMAP,3*(1<<bdev->color_info.depth));
- WriteChunkBytes(bdev->iff,bdev->palette,3*(1<<bdev->color_info.depth));
- PopChunk(bdev->iff);
- }
- }
-
- private int
- ilbm8_print_page(gx_device_printer *pdev,FILE *dummy)
- {
- const uint outputw=RowBytes(bdev->width);
- const uint line_size=gdev_prn_raster((gx_device_printer *)bdev);
- const uint pack_size=MaxPackedSize(outputw);
- byte *const data =(byte *)gs_malloc(1,line_size,"ilbm8_print_page");
- byte *const output=(byte *)gs_malloc(8,outputw ,"ilbm8_print_page");
- byte *const pack =
- (bdev->compression==cmpByteRun1)
- ?(byte *)gs_malloc(1,pack_size,"ilbm8_print_page"):NULL;
- byte *bp,*planep;
- unsigned long line;
- uint x0,packedbytes;
- byte mask,x1,plane;
-
- if(pack!=NULL||bdev->compression!=cmpByteRun1) {
- if(output!=NULL) {
- if (data != NULL) {
- print_iff_header(pdev);
- PushChunk(bdev->iff,ID_ILBM,ID_BODY,IFFSIZE_UNKNOWN);
- for(line=0;line<bdev->height;line++) {
- gdev_prn_copy_scan_lines((gx_device_printer *)bdev,line,data,line_size);
- memset(output,0,8*outputw);
- planep=output;
- for(mask=1<<0;mask;mask<<=1) {
- bp=data;
- for(x0=outputw;x0;x0--) {
- for(x1=8;x1;x1--) {
- (*planep)<<=1; *planep|=(*bp++&mask)==mask;
- }
- planep++;
- }
- }
- if(bdev->compression==cmpByteRun1) {
- for(plane=bdev->color_info.depth,planep=output;
- plane>0;
- plane--,planep+=outputw) {
- packedbytes=packrow(planep,pack,outputw);
- WriteChunkBytes(bdev->iff,pack,packedbytes);
- }
- }
- else {
- WriteChunkRecords(bdev->iff,output,outputw,bdev->color_info.depth);
- }
- }
- PopChunk(bdev->iff); /* Pop Body Chunk */
- gs_free(data,1,line_size,"ilbm8_print_page");
- }
- else return -1;
- gs_free(output,8,outputw,"ilbm8_print_page");
- }
- else return -1;
- if(bdev->compression==cmpByteRun1) {
- gs_free(pack,1,pack_size,"ilbm8_print_page");
- }
- }
- else return -1;
- return 0;
- }
-
- /*
- * Print a color-mapped page with 24 Bit
- *
- * This function is too different from ilbm8_print_page, so for
- * higher output speed the main loop is rewritten
- *
- */
- private int
- ilbm24_print_page(gx_device_printer *pdev,FILE *dummy)
- {
- const uint outputw=RowBytes(bdev->width);
- const uint line_size=gdev_prn_raster((gx_device_printer *)bdev);
- const uint pack_size=MaxPackedSize(outputw);
- byte *const data = (byte *)gs_malloc(line_size,1,"ilbm24_print_page");
- byte *const output=(byte *)gs_malloc(24,outputw ,"ilbm24_print_page");
- byte *const pack =
- (bdev->compression==cmpByteRun1)
- ?(byte *)gs_malloc(1,pack_size,"ilbm8_print_page"):NULL;
- byte *bp,*planep,*red,*green,*blue;
- unsigned long line;
- uint x0,packedbytes;
- byte mask,x1,plane;
-
- if(pack!=NULL||bdev->compression!=cmpByteRun1) {
- if(output!=NULL) {
- if (data != NULL) {
- print_iff_header(pdev);
- PushChunk(bdev->iff,ID_ILBM,ID_BODY,IFFSIZE_UNKNOWN);
- for(line=0;line<bdev->height;line++) {
- gdev_prn_copy_scan_lines((gx_device_printer *)bdev,line,data,line_size);
- memset(output,0,24*outputw);
- red =output;
- green=red +8*outputw;
- blue =green+8*outputw;
- for(mask=0;mask<8;mask++) {
- bp=data;
- for(x0=outputw;x0;x0--) {
- for(x1=8;x1;x1--) {
- *red =*red <<1|*bp++>>mask&1;
- *green=*green<<1|*bp++>>mask&1;
- *blue =*blue <<1|*bp++>>mask&1;
- }
- red++;
- green++;
- blue++;
- }
- }
- if(bdev->compression==cmpByteRun1) {
- for(plane=bdev->color_info.depth,planep=output;
- plane>0;
- plane--,planep+=outputw) {
- packedbytes=packrow(planep,pack,outputw);
- WriteChunkBytes(bdev->iff,pack,packedbytes);
- }
- }
- else {
- WriteChunkRecords(bdev->iff,output,outputw,bdev->color_info.depth);
- }
- } /* end for each line */
- PopChunk(bdev->iff); /* Pop Body Chunk */
- gs_free(data,1,line_size,"ilbm24_print_page");
- }
- else return -1;
- gs_free(output,8,outputw,"ilbm24_print_page");
- }
- else return -1;
- if(bdev->compression==cmpByteRun1) {
- gs_free(pack,1,pack_size,"ilbm24_print_page");
- }
- }
- else return -1;
- return 0;
- }
-
- /*
- * Open the current page for printing.
- */
- int
- gdev_ilbm_open_file(gx_device * pdev)
- {
- long ifferror;
- int ret=0;
- char *fname = bdev->fname;
- char pfname[sizeof(bdev->fname) + 10];
-
- if (strchr(fname, '%')) {
- sprintf(pfname, fname, bdev->page_count);
- fname = pfname;
- }
- if(IFFParseBase==NULL) {
- IFFParseBase=(struct IFFParseBase *)OpenLibrary("iffparse.library",33);
- if(IFFParseBase==NULL) {
- eprintf("gdev_ilbm_open_file(): cannot open iffparse.library\n");
- ret=-1;
- }
- }
- if(ret==0) {
- bdev->iff=AllocIFF();
- if(bdev->iff==NULL) {
- eprintf("gdev_ilbm_open_file(): cannot allocate IFFHandle\n");
- ret=-1;
- }
- }
- if(ret==0) {
- bdev->iff->iff_Stream=Open(fname,MODE_NEWFILE);
- if(bdev->iff->iff_Stream==NULL) {
- eprintf1("gdev_ilbm_open_file(): cannot open file %s for writing\n",fname);
- ret=-1;
- }
- }
- if(ret==0) {
- InitIFFasDOS(bdev->iff);
- ifferror=OpenIFF(bdev->iff,IFFF_WRITE);
- if(ifferror!=0) {
- eprintf1("gdev_ilbm_open_file(): iff-error %d\n",ifferror);
- ret=-1;
- }
- }
- if(ret==0) {
- PushChunk(bdev->iff,ID_ILBM,ID_FORM,IFFSIZE_UNKNOWN);
- }
- return ret;
- }
-
- /*
- * Close the current page.
- */
- int
- gdev_ilbm_close_file(gx_device *pdev)
- {
- /* if (strchr(bdev->fname, '%')) { */
- PopChunk(bdev->iff); /* Pop FORM chunk */
- CloseIFF(bdev->iff);
- if(bdev->iff->iff_Stream!=NULL) Close((BPTR)bdev->iff->iff_Stream);
- bdev->iff->iff_Stream = NULL;
- FreeIFF(bdev->iff);
- if(IFFParseBase!=NULL) {
- CloseLibrary((struct Library *)IFFParseBase);
- IFFParseBase=NULL;
- }
- /* } */
- return 0;
- }
-
- /*
- * Generic routine to send the page to the printer.
- *
- * Note that num_copies is currently ignored: this is wrong.
- */
- int
- gdev_ilbm_output_page(gx_device *pdev, int num_copies, int flush)
- {
- int code;
-
- bdev->page_count++;
- if ((code = gdev_ilbm_open_file(pdev)) >= 0) {
- /* print the accumulated page description */
- if ((code= (*bdev->print_page) ((gx_device_printer *)pdev,NULL)) >= 0) {
- if ((code = gdev_ilbm_close_file(pdev)) >= 0) {
- if (bdev->buffer_space) { /* reinitialize clist for writing */
- code = (*gs_clist_device_procs.output_page) (pdev, num_copies, 0);
- }
- }
- }
- }
- return code;
- }
-
-
- int
- gdev_ilbm_open(gx_device * pdev)
- {
- gdev_prn_open(pdev);
-
- bdev->iff=NULL;
- memset(bdev->palette,0,sizeof(bdev->palette));
- bdev->ncols = 0;
- bdev->compression=COMPRESSION;
-
- if(bdev->color_info.depth==8) { /* CLUT setup */
- gx_color_index color;
- byte r, g, b;
-
- /* allocate black & white as first 2 colors */
- SETRGB( 0, 0, 0);
- SETRGB(255, 255, 255);
-
- /* allocate evenly space color cube */
- while (bdev->ncols < 64) {
- color = bdev->ncols - 1;
- r = (color & 0x03) *((1<<bdev->color_info.depth)-1)/(4-1);
- g = ((color & 0x0c)>>2)*((1<<bdev->color_info.depth)-1)/(4-1);
- b = ((color & 0x30)>>4)*((1<<bdev->color_info.depth)-1)/(4-1);
- SETRGB(r, g, b);
- }
- }
- }
-